home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / emu / APCNames12a.lha / APCNames / Sources.Amiga / APCNames.c next >
Encoding:
C/C++ Source or Header  |  1993-12-07  |  11.1 KB  |  388 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1993 by Rainer Koppler
  4.  *
  5.  *    Name .....: APCNames.c
  6.  *    Created ..: Friday 5-Mar-93 19:31:41
  7.  *    Revision .: 6
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    07-Dec-93   Rainer Koppler         enhanced encoding of long names
  12.  *    23-Sep-93   Rainer Koppler         "S:APCNames.types" support added
  13.  *    09-Sep-93   Rainer Koppler         Symantec C++ support added
  14.  *    15-Jul-93   Rainer Koppler         MS-Word support added
  15.  *    23-Mar-93   Rainer Koppler         Bug fix: multiple periods handled
  16.  *      17-Mar-93   Rainer Koppler         Bug fix: disk entry only at root level
  17.  *    05-Mar-93   Rainer Koppler         Created this file!
  18.  *
  19.  ****************************************************************************
  20.  *
  21.  *      Utility for creating original file names for MS-DOS file names
  22.  *      from the APCINFO.DAT file created by the Mac tool AccessPC.
  23.  *
  24.  * $Revision Header ********************************************************/
  25.  
  26. #include "APCNames.h"
  27. #include "Types.h"
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32.  
  33. #ifndef AMIGA
  34. extern int strnicmp (char *, char *, int);
  35. extern int stricmp (char *, char *);
  36. #endif
  37.  
  38. /*-------------------------------------------------------------------
  39. **  SetPattern/NextEntry are my own Amiga-specific pattern-matching
  40. **   routines. I suppose there is no need for them for UN*X... :^)
  41. **-------------------------------------------------------------------
  42. */
  43.  
  44. #ifdef AMIGA
  45. #include "Wildcard.h"
  46. #else
  47. static char *fnDummy;
  48. static void  SetPattern (char *fileName)
  49.   fnDummy = fileName;
  50. }
  51. static char *NextEntry (void)
  52. {  
  53.   char *fn = fnDummy;
  54.   fnDummy = NULL;
  55.   return fn;
  56. }
  57. #endif
  58.  
  59.  
  60. /*-------------------------------------------------------------------
  61. **  Each APCINFO.DAT file consists of several records denoting
  62. **  disk or file entries. Each record has a length of 80 bytes.
  63. **  The first record always denotes a disk entry, all subsequent
  64. **  records are file entries.
  65. **  After each 12 entries there are 64 bytes with undefined contents.
  66. **-------------------------------------------------------------------
  67. */
  68.  
  69. #define APC_ENTRY_SIZE  sizeof(union APCEntry)
  70. #define APC_PAD_SIZE    0x40
  71.  
  72. union APCEntry {
  73.  
  74.   UBYTE    ae_Data[80];
  75.  
  76.   struct DiskEntry {
  77.     UBYTE  de_Length;        /*length of disk name*/
  78.     UBYTE  de_Pad[79];       /*disk name and other data*/
  79.   } de;
  80.  
  81.   struct FileEntry {
  82.     UBYTE  fe_Length;        /*length of file name*/
  83.     char   fe_Name[31];      /*file name characters*/
  84.     ULONG  fe_Type;          /*Macintosh type ID*/
  85.     ULONG  fe_Creator;       /*Macintosh creator ID*/
  86.     UBYTE  fe_Pad1[23];      /*undocumented data*/
  87.     UBYTE  fe_Flags;         /*file visible <=> 0 (?)*/
  88.     char   fe_MSDOSName[8];  /*file name padded with blanks*/
  89.     char   fe_MSDOSExt[3];   /*extension padded with blanks*/
  90.     UBYTE  fe_Pad2[5];       /*always zero*/
  91.   } fe;
  92.  
  93. };
  94.  
  95.  
  96. /*----------------------------- global data ---------------------------------*/
  97.  
  98. static FILE *apcInfoDat;
  99. static union APCEntry *entry;
  100. static char lngName[32],shtName[13],*sptr;
  101.  
  102. static const char versionStr[] = {
  103.   "\0$VER: APCNames 1.2 by Rainer Koppler (7.12.93)"
  104. };
  105.  
  106.  
  107. /*---------------- disk entry for empty disk (view by name) -----------------*/
  108.  
  109. static ULONG de_Empty[] = {
  110.   0x0A526169, 0x6E657220, 0x31001600, 0x0002A002,
  111.   0x02000000, 0x00000000, 0x00000000, 0x00000001,
  112.   0x002E0008, 0x00EA019C, 0x01000070, 0x02480200,
  113.   0xFFF8FFF0, 0x00000000, 0x00008000, 0x00000002,
  114.   0x7FA95F49, 0x6E736967, 0x6E696100, 0x00000000
  115. };
  116.  
  117. /*------------------------- universal file entry ----------------------------*/
  118.  
  119. static ULONG fe_Default[] = {
  120.   0x00000000, 0x00000000, 0x00000000, 0x00000000,
  121.   0x000D0D90, 0x0000000F, 0x000000E5, 0x000D0D90,
  122.   0x00000000, 0x00000000, 0x0100FFFF, 0xFFFF0000, /* TYPE, CREATOR, ... */
  123.   0x00000000, 0x00000000, 0x00000000, 0x00000000,
  124.   0x00000000, 0x00000000, 0x00000000, 0x00000000
  125. };
  126.  
  127.  
  128. /*---------------------------------------------------------------------------*/
  129.  
  130. static void Pas2CStr (UBYTE *ps, char *cs)
  131. {
  132.  UBYTE len = *ps;
  133.  
  134.  strncpy(cs,(char *)ps+1,len);
  135.  *(cs+len) = '\0';
  136. }
  137.  
  138. /*---------------------------------------------------------------------------*/
  139.  
  140. static void C2PasStr (char *cs, UBYTE *ps)
  141. {
  142.  UBYTE len = strlen(cs);
  143.  
  144.  strcpy((char *)ps+1,cs);
  145.  *ps = len;
  146. }
  147.  
  148. /*---------------------------------------------------------------------------*/
  149.  
  150. static void Long2Short (char *fileName)
  151. {
  152.   char *dotPtr,*lptr,ch,orgCh;
  153.   struct TCInfo *tci;
  154.   int i,stubIdx,state;
  155.   union APCEntry *tstEntry;
  156.   LONG fp;
  157.  
  158. /*--- copy entry template to "entry" and insert TYPE/CREATOR ---*/
  159.   memcpy(entry,fe_Default,APC_ENTRY_SIZE);
  160.   tci = TCInfoFor(fileName);
  161.   entry->fe.fe_Type = tci->tci_Type;
  162.   entry->fe.fe_Creator =tci->tci_Creator;
  163. /*--- insert original file name ---*/
  164.   C2PasStr(fileName,(UBYTE *)entry);
  165. /*--- 1. encode original file name to "shtName" (MS-DOS format) ---*/
  166.   for(i=0,sptr=shtName,lptr=fileName; i<8 && *lptr!='\0' && *lptr!='.';
  167.       sptr++,lptr++,i++)
  168.     *sptr = toupper(*lptr);
  169.   stubIdx = lptr-fileName; /* where the stub character would be placed */
  170.   if(stubIdx == 8) stubIdx--;
  171.   dotPtr = strchr(fileName,'.');
  172.   if(dotPtr) {
  173.     for(; i<8; i++,sptr++) *sptr = ' ';
  174.     for(lptr=dotPtr+1; i<11 && *lptr!='\0'; lptr++)
  175.       if(*lptr != '.') {
  176.         *sptr = toupper(*lptr);
  177.         sptr++;
  178.         i++;
  179.       }
  180.   }
  181.   for(; i<11; i++,sptr++) *sptr = ' ';
  182. /*--- 2. seek existing entry with same MS-DOS name & modify new name if so ---*/
  183.   fseek(apcInfoDat,0L,SEEK_SET);
  184.   state = 0;
  185.   orgCh = shtName[stubIdx];
  186.   if(!(tstEntry=malloc(APC_ENTRY_SIZE))) {
  187.     printf("*** No memory for test entry block.\n");
  188.     exit(EXIT_FAILURE);
  189.   }
  190.   while(fread(tstEntry,APC_ENTRY_SIZE,1,apcInfoDat) > 0) {
  191.     if(!strncmp(tstEntry->fe.fe_MSDOSName,shtName,11)) {
  192.       do {
  193.         if(state == 0)
  194.           ch = '&';
  195.         else if(state>=1 && state<=10)
  196.           ch = '0'+state-1;
  197.         else if(state>=11 && state<=36)
  198.           ch = 'A'+state-11;
  199.         else {
  200.           printf("*** Encoding possibilities exceeded. Try to rename some files.\n");
  201.           exit(EXIT_FAILURE);
  202.         }
  203.         state++;
  204.       } while(ch == orgCh);
  205.       shtName[stubIdx] = ch;
  206.     }
  207.     fp = ftell(apcInfoDat);
  208.     if(fp % 0x0400 == 0x03C0)
  209.       fread(tstEntry,APC_PAD_SIZE,1,apcInfoDat);
  210.   }
  211.   free(tstEntry);
  212. /*--- 3. insert MS-DOS file name into entry & prepare "shtName" for rename ---*/
  213.   for(i=0,sptr=shtName,lptr=entry->fe.fe_MSDOSName; i<11; i++,sptr++,lptr++) 
  214.     *lptr = *sptr;
  215.   for(i=0,sptr=shtName,lptr=entry->fe.fe_MSDOSName; i<11; i++) {
  216.     if(i==8 && dotPtr && *(dotPtr+1)) {
  217.       *sptr = '.';
  218.       sptr++;
  219.     }
  220.     if(*lptr != ' ') {
  221.       *sptr = *lptr;
  222.       sptr++;
  223.     }
  224.     lptr++;
  225.   }
  226.   *sptr = 0;
  227. }
  228.  
  229. /*---------------------------------------------------------------------------*/
  230.  
  231. static void Short2Long (void)
  232. {
  233.   int i;
  234.   char *ptr;
  235.  
  236.   if(entry->fe.fe_Length > 31) {
  237.     *shtName = '\0'; *lngName = '\0';
  238.     return;
  239.   }
  240.   Pas2CStr((UBYTE *)entry,lngName);
  241.   sptr = shtName;
  242.   ptr = entry->fe.fe_MSDOSName;
  243.   for(i=0; i<8 && *ptr!=' '; sptr++,ptr++,i++)
  244.     *sptr = *ptr;
  245.   ptr = entry->fe.fe_MSDOSExt;
  246.   if(*ptr != ' ') {
  247.     *sptr = '.';
  248.     sptr++;
  249.   }
  250.   for(i=0; i<3 && *ptr!=' '; sptr++,ptr++,i++)
  251.     *sptr=*ptr;
  252.   *sptr = '\0';
  253. }
  254.  
  255. /*---------------------------------------------------------------------------*/
  256.  
  257. static BOOL EntryExistsFor (char *fileName)
  258. {
  259.   BOOL fnd = FALSE;
  260.   LONG fp;
  261.  
  262.   fseek(apcInfoDat,0L,SEEK_SET);
  263.   while(!fnd && fread(entry,APC_ENTRY_SIZE,1,apcInfoDat) > 0) {
  264.     Pas2CStr((UBYTE *)entry,lngName);
  265.     if(!(fnd = !stricmp(fileName,lngName))) {
  266.       fp = ftell(apcInfoDat);
  267.       if(fp % 0x0400 == 0x03C0)
  268.         fread(entry,APC_PAD_SIZE,1,apcInfoDat);
  269.     }
  270.   }
  271.   return(fnd);
  272. }
  273.  
  274. /*---------------------------------------------------------------------------*/
  275.  
  276. main (int argc, char *argv[])
  277. {
  278.   int cnt,fnCnt,total;
  279.   char *fn;
  280.   LONG fp;
  281.  
  282.   printf("\n»»APCNames«« - AccessPC renaming utility v1.2\n\n");
  283.  
  284.   if(--argc > 0 && strncmp(argv[1],"-c",2)) {
  285.     printf("USAGE: %s [ -c[<config>] <file> { <file> }]\n",argv[0]);
  286.     exit(EXIT_FAILURE);
  287.   }
  288.  
  289.   if(!(entry=malloc(APC_ENTRY_SIZE))) {
  290.     printf("*** No memory for entry block.\n");
  291.     exit(EXIT_FAILURE);
  292.   }
  293.  
  294.   fnCnt = 0;
  295.   total = 0;
  296.  
  297. /*--- transform long names to short names and create/update APCINFO file ---*/
  298.   if(argc > 0) {
  299.     if(!(apcInfoDat=fopen("APCINFO.DAT","a+"))) {
  300.       printf("*** Cannot open APCINFO.DAT for update.\n");
  301.       exit(EXIT_FAILURE);
  302.     }
  303.   /*--- if new file then create (empty) disk entry at beginning ---*/
  304.     fseek(apcInfoDat,0L,SEEK_END);
  305.     if(ftell(apcInfoDat) == 0)
  306.       fwrite(de_Empty,1,APC_ENTRY_SIZE,apcInfoDat);
  307.   /*--- configuration file specified ? ---*/
  308.     if(strlen(argv[1]) > 2)
  309.       ReadTypes(argv[1]+2);
  310.     else
  311.       ReadTypes(DEFAULT_CONFIG);
  312.   /*--- process file patterns ---*/
  313.     for(cnt=2; cnt<=argc; cnt++) {
  314.       SetPattern(argv[cnt]);
  315.       while(fn = NextEntry()) {
  316.       /*--- lookup APCINFO.DAT for existing entry ---*/
  317.         if(!EntryExistsFor(fn)) {
  318.           fseek(apcInfoDat,0L,SEEK_END);
  319.           fp = ftell(apcInfoDat);
  320.           if(fp % 0x0400 == 0x03C0) {
  321.             memset(entry,0,APC_PAD_SIZE);
  322.             fwrite(entry,APC_PAD_SIZE,1,apcInfoDat);
  323.           }
  324.           Long2Short(fn);
  325.           fseek(apcInfoDat,0L,SEEK_END);
  326.           fwrite(entry,APC_ENTRY_SIZE,1,apcInfoDat);
  327.           printf("renaming \"%s\" to \"%s\"...",fn,shtName);
  328.           total++;
  329.           if(!rename(fn,shtName)) {
  330.             printf("ok\n");
  331.             fnCnt++;
  332.           }
  333.           else
  334.             printf("failed\n");
  335.         }
  336.         else
  337.           printf("\"%s\" already exists - skipped.\n",fn); 
  338.       }
  339.     }
  340.     fclose(apcInfoDat);
  341.     printf("\n%d file(s) of %d renamed successfully.\n",fnCnt,total);
  342.   }
  343. /*--- get contents of APCINFO file and transform short names to long names ---*/
  344.   else {
  345.     if(!(apcInfoDat=fopen("APCINFO.DAT","r"))) {
  346.       printf("*** Cannot open APCINFO.DAT for input.\n");
  347.       exit(EXIT_FAILURE);
  348.     }
  349.     cnt = 0;
  350.     while(fread(entry,APC_ENTRY_SIZE,1,apcInfoDat) > 0) {
  351.     /*--- D I S K  E N T R Y ---*/
  352.       if(entry->fe.fe_MSDOSName[1] == '©') {
  353.         Pas2CStr((UBYTE *)entry,lngName);
  354.         printf("Disk name: %s\n\n",lngName);
  355.       }
  356.     /*--- F I L E  E N T R Y ---*/
  357.       else {
  358.       /*--- create MS-DOS name and original name of entry data ---*/
  359.         Short2Long();
  360.       /*--- rename only if valid file entry ---*/
  361.         if(entry->fe.fe_Type == TYPE_TEXT || entry->fe.fe_Type == TYPE_WDBN) {
  362.           printf("renaming \"%s\" to \"%s\"...",shtName,lngName);
  363.           total++;
  364.           if(!rename(shtName,lngName)) {
  365.             printf("ok\n");
  366.             fnCnt++;
  367.           }
  368.           else
  369.             printf("failed\n");
  370.         }
  371.         else
  372.           printf("ignoring \"%s\" (\"%s\")\n",shtName,lngName);
  373.       }
  374.       cnt++;
  375.     /*--- skip 64 bytes after each 12 records ---*/
  376.       if(cnt == 12) {
  377.         fread(entry,APC_PAD_SIZE,1,apcInfoDat);
  378.         cnt = 0;
  379.       }
  380.     }
  381.     fclose(apcInfoDat);
  382.     printf("\n%d file(s) of %d renamed successfully.\n",fnCnt,total);
  383.   }
  384.   FreeTypes();
  385.   free(entry);
  386. }
  387.